package net.jielan188.hd.bean.base;

import net.jielan188.hd.util.CommonUtils;
import net.jielan188.hd.util.Log;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created by hgg on 2017/1/11.
 */
@Component
public class MyBatisBaseI {

    /**
     * 获取分页查询条件
     * @param o
     * @return
     */
    public String getPageSqlSql(Object o ){

        StringBuilder sql = new StringBuilder( "select * from xf_" );
        try {

            if( o == null ){
                return null;
            }
            Class cls = o.getClass();
            sql.append( CommonUtils.firstNameToSmall( CommonUtils.camel4underline( cls.getSimpleName() ) ) ).append( " " );
            commSqlSelect( sql,o );
            Integer pageNo = (Integer) getVaule( o,"pageNo" );
            Integer pageSize = (Integer) getVaule( o,"pageSize" );
            dealPageCondition( o,pageNo,pageSize,sql );
        }catch ( Exception e ){
            Log.error( e.getMessage() );
            throw new RuntimeException("SQL 异常");
        }
        return sql.toString();
    }

    /**
     * 获取总数量
     * @param o
     * @return
     */
    public String getTotalCountSql(Object o ){

        StringBuilder sql = new StringBuilder( "select count(1) from xf_" );
        try {

            if( o == null ){
                return null;
            }
            Class cls = o.getClass();
            sql.append( CommonUtils.firstNameToSmall( CommonUtils.camel4underline( cls.getSimpleName() ) ) ).append( " " );
            commSqlSelect( sql,o );
        }catch ( Exception e ){
            Log.error( e.getMessage() );
            throw new RuntimeException("SQL 异常");
        }
        return sql.toString();
    }

    /**
     * 查询详情
     * @param o
     * @return
     */
    public String getDetailSql(Object o ){

        StringBuilder sql = new StringBuilder( "select * from xf_" );
        try {
            if( o == null ){
                return null;
            }
            Class cls = o.getClass();
            sql.append( CommonUtils.firstNameToSmall( CommonUtils.camel4underline( cls.getSimpleName() ) ) ).append( " " );
            commSqlSelect( sql,o );
            sql.append( " limit 0,1" );
        }catch ( Exception e ){
            Log.error( e.getMessage() );
            throw new RuntimeException("SQL 异常");
        }
        return sql.toString();
    }

    /**
     * 删除SQL
     * @param o
     * @return
     */
    public String getDeleteSql(Object o ){

        StringBuilder sql = new StringBuilder( "delete from xf_" );
        try {
            if( o == null ){
                return null;
            }
            Class cls = o.getClass();
            String tableName = CommonUtils.firstNameToSmall( CommonUtils.camel4underline( cls.getSimpleName() ) );
            sql.append( tableName ).append( " " );
            commSqlSelect( sql,o );
        }catch ( Exception e ){
            Log.error( e.getMessage() );
            throw new RuntimeException("SQL 异常");
        }
        return sql.toString();
    }

    /**
     * 保存SQL
     * @param o
     * @return
     */
    public String getSaveAddSql(Object o ){

        StringBuilder sql = new StringBuilder( "insert into xf_" );
        try {

            if( o == null ){
                return null;
            }
            Class cls = o.getClass();
            String tableName = CommonUtils.firstNameToSmall( CommonUtils.camel4underline( cls.getSimpleName() ) );
            sql.append( tableName ).append( "(" );
            Field[] fields = cls.getDeclaredFields();
            Integer k = 0;
            for (Integer i = 0; i < fields.length ; i ++ ){
                if( getVaule( o,fields[i].getName() ) != null ){
                    if( k != 0 )
                        sql.append( "," );
                    sql.append( CommonUtils.camel4underline( fields[i].getName() ) );
                    k++;
                }
            }
            sql.append( ") values(" );

            k = 0;
            for (Integer j = 0; j < fields.length ; j ++ ){
                if( getVaule( o,fields[j].getName() ) != null ){
                    if( k != 0 ){
                        sql.append( "," );
                    }
                    sql.append( "'" ).append( getVaule( o,fields[j].getName() ) ).append( "'" );
                    k++;
                }
            }
            sql.append( ")" );
        }catch ( Exception e ){
            Log.error( e.getMessage() );
            throw new RuntimeException("SQL 异常");
        }
        return sql.toString();
    }

    /**
     * 更新SQL
     * @param o
     * @return
     */
    public String getUpdateSql(Object o ){

        StringBuilder sql = new StringBuilder( "update xf_" );
        try {

            if( o == null ){
                return null;
            }
            Class cls = o.getClass();
            String tableName = CommonUtils.firstNameToSmall( CommonUtils.camel4underline( cls.getSimpleName() ) );
            sql.append( tableName ).append( " set " );
            Field[] fields = cls.getDeclaredFields();
            Integer k = 0;
            for (Integer i = 0; i < fields.length ; i ++ ){
                if( k != 0 )
                    sql.append( "," );
                if( getVaule( o,fields[i].getName() ) != null ){
                    k ++;
                    sql.append( CommonUtils.camel4underline( fields[i].getName() ) ).append( "=" )
                            .append( "'" ).append( getVaule( o,fields[i].getName() ) ).append( "'" );
                }
            }
            commSqlSelect( sql,o );
        }catch ( Exception e ){
            Log.error( e.getMessage() );
            throw new RuntimeException("SQL 异常");
        }
        return sql.toString();
    }

    /**
     * 通用查询条件
     * @param sql
     * @param o
     */
    private void commSqlSelect(StringBuilder sql, Object o ){

        Class cls = o.getClass();
//        sql.append( firstNameToSmall( cls.getSimpleName() ) ).append( " " );
        Class clazzP = cls.getSuperclass();
        Field[] fields = clazzP.getDeclaredFields();
        for ( Field field : fields ){

            if( StringUtils.equals( field.getName(),"myBatisSelect" ) ){
                dealSelectCondition( o,field.getName(),sql );
            }
            else if( StringUtils.equals( field.getName(),"orderByCondition" ) ){
                dealOrderByCondition( o,field.getName(),sql );
            }
            else if( StringUtils.equals( field.getName(),"groupByCondition" ) ){
                dealGroupCondition( o,field.getName(),sql );
            }
        }
    }

    /**
     * 拼接一般查询条件
     * @param o
     * @param name
     * @param sql
     */
    private void dealSelectCondition(Object o, String name, StringBuilder sql ){

        if( getVaule( o,name ) == null ){
            return;
        }
        MyBatisSelect myBatisSelect = (MyBatisSelect) getVaule( o,name );
        if( myBatisSelect != null && StringUtils.isNotBlank( myBatisSelect.getSelectSql() ) ){
            sql.append( myBatisSelect.getSelectSql() );
        }
    }

    /**
     * 拼接分页
     * @param o
     * @param sql
     */
    private void dealPageCondition(Object o, Integer pageNo, Integer pageSize, StringBuilder sql ){

        if( pageNo == null ){
            pageNo = 1;
        }
        if( pageSize == null ){
            pageSize = 10;
        }
        Integer start = ( pageNo - 1 ) * pageSize;
        sql.append( " limit " ).append( start );
        sql.append( "," ).append( pageSize );
    }

    /**
     * 分组条件
     * @param o
     * @param name
     * @param sql
     */
    private void dealGroupCondition(Object o, String name, StringBuilder sql ){

        if( getVaule( o,name ) == null ){
            return;
        }
        String selectField = (String) getVaule( o,name );
        String[] fields = selectField.split( "," );
        if( fields.length < 1 || fields == null ){
            return;
        }
        for (Integer i = 0; i < fields.length ; i ++ ){
            String thisName = CommonUtils.camel4underline( fields[i] );
            if( i == 0 ){
                sql.append( " group by " ).append( thisName );
            }else {
                sql.append( " , " ).append( thisName );
            }
        }
    }

    /**
     * 排序规则设置（0，升序 1降序）
     * @param o
     * @param name
     * @param sql
     */
    private void dealOrderByCondition(Object o, String name, StringBuilder sql ){

        if( getVaule( o,name ) == null ){
            return;
        }
        String selectField = (String) getVaule( o,name );
        String[] fields = selectField.split( "," );
        if( fields.length < 1 || fields == null ){
            return;
        }
        for (Integer i = 0; i < fields.length ; i ++ ){
            String[] thisField = fields[i].split( "_" );
            String thisName = CommonUtils.firstNameToSmall( thisField[0] );
            thisName = CommonUtils.camel4underline( thisName );
            if( i == 0 ){
                sql.append( " order by " );
            }else {
                sql.append( "," );
            }
            if( StringUtils.equals( thisField[1],"1" ) ){
                sql.append( thisName ).append( " DESC" );
            }else {
                sql.append( thisName ).append( " ASC" );
            }
        }
    }

    /**
     * 获取到Get 方法的值
     * @param o
     * @param methodName
     * @return
     */
    private Object getVaule(Object o, String methodName ){

        Method method = null;
        Class cls = null;
        try {

            cls = o.getClass();
            method = cls.getMethod( "get" + CommonUtils.firstNameToLarge( methodName ) );
            return method.invoke( o );
        }catch ( Exception e ){
            return null;
        }
    }
}
